package rad.framework.web;

import java.io.IOException;
import java.util.Arrays;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import rad.framework.lang.ExceptionUtil;
import rad.framework.seam.AbstractEditor;
import rad.framework.seam.AbstractFinder;

import org.hibernate.validator.InvalidStateException;
import org.hibernate.validator.InvalidValue;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.servlet.ContextualHttpServletRequest;
import org.jboss.seam.web.AbstractResource;

@Scope(ScopeType.APPLICATION)
@Name("rad.framework.web.exportResource")
@BypassInterceptors
public class ExportResource extends AbstractResource {

	@Override
	public String getResourcePath() {
		return "/export";
	}

	@Override
	public void getResource(final HttpServletRequest request,
			final HttpServletResponse response) throws ServletException,
			IOException {

		// Wrap this, we need an ApplicationContext
		new ContextualHttpServletRequest(request) {
			@Override
			public void process() throws IOException {
				doWork(request, response);
			}
		}.run();
	}

	public void doWork(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		try {
			response.setContentType("text/xml");
			final String componentName = request.getParameter("component");
			Object component = Component.getInstance(componentName);
			if (component instanceof AbstractFinder) {
				AbstractFinder<?> finder = (AbstractFinder<?>) component;
				finder.getExportXml(response.getOutputStream());
			} else if (component instanceof AbstractEditor) {
				AbstractEditor<?> editor = (AbstractEditor<?>) component;
				editor.getExportXml(response.getOutputStream());
			} else {
				throw new ServletException(
						"The requested component is not a finder or editor: "
								+ componentName);
			}

			response.getOutputStream().flush();
		} catch (Exception e) {
			Throwable cause = ExceptionUtil.getRootCause(e);
			if (cause instanceof InvalidStateException) {
				InvalidValue[] errors = ((InvalidStateException) cause)
						.getInvalidValues();
				response.reset();
				response.getOutputStream().println("Validation Errors");
				response.getOutputStream().println("-----------------");
				response.getOutputStream().println(Arrays.toString(errors));
				response.getOutputStream().flush();
			} else {
				response.sendError(
						HttpServletResponse.SC_INTERNAL_SERVER_ERROR, cause
								.getMessage());
			}
		}
	}
}
